package serveratm;

import org.apache.log4j.Logger;

import java.io.*;
import java.net.Socket;

public class ServerPerformer extends Thread implements UserData {
    public enum Keywords {
        ;
        private static final Integer OVERDRAFT = 1000;
        private static final String USERPIN = "1234";
        private static final String USERCARD = "4769304941841937";
        private static volatile Integer TOTAL = 10500;
        public static final String NO_FUNDS = "INSUFFICIENT FUNDS";
        public static final String BALANCE = "THE BALANCE ON YOUR CARD IS   ";
        private static final String WRONG_PIN = "ENTERED WRONG PIN NUMBER";
        private static final String GET = "GET";
    }

    ;
    Socket socket;
    String message;
    String checkPin;
    String toGetCashOrder;
    String checkUserCard;

    private static final Logger logger = Logger.getLogger(ServerPerformer.class);

    public ServerPerformer(Socket soc) {
        socket = soc;
        start();
    }

    public void run() {

        try {
            InputStream inputS = socket.getInputStream();
            DataInputStream inputData = new DataInputStream(inputS);
            message = inputData.readUTF();
            logger.info("received :" + message);
            if (checkPin(Keywords.USERPIN, Keywords.USERCARD)) {
                return;
            }
            actionRequired();
            OutputStream outputS = socket.getOutputStream();
            DataOutputStream outputData = new DataOutputStream(outputS);
            outputData.writeUTF(Keywords.BALANCE + Keywords.TOTAL.toString());
            logger.info("sent " + Keywords.BALANCE + Keywords.TOTAL.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            closeSocket();
        }
    }

    public void closeSocket() {
        try {
            socket.close();
        } catch (IOException e) {
            logger.error("Socket was not closed");
        }
    }

    public void actionRequired() {
        toGetCashOrder = message.substring(39, 42);
        if (toGetCashOrder.equals(Keywords.GET)) {
            logger.debug("user required get action");
            getMoney();
        }
    }

    public void getMoney() {
        System.out.println(message);
        String wantCash = message.substring(48, 52);
        logger.info("received request for " + wantCash);
        int value = Integer.parseInt(wantCash);
        System.out.println(value);
        if (value <= Keywords.TOTAL + Keywords.OVERDRAFT) {
            Keywords.TOTAL = Keywords.TOTAL - value;
            doAtmGiveMoney(value);
            logger.info("request approved");
            sentSmsNotification(value);
        } else {
            System.out.println(Keywords.NO_FUNDS);
            logger.warn("No funds");
            sentSmsNotification();
        }
    }


    public boolean sentSmsNotification() {
        logger.info("attempt to withdraw money");
        return true;
    }

    public boolean sentSmsNotification(int value) {
        logger.info("sms about withdrawn from account was sent. Withdraw " + value);
        return true;
    }

    public boolean doAtmGiveMoney(int value) {
        // Request for the hardware method should be added here
        logger.info("money to withdraw , " + value);
        return true;
    }


    public boolean checkPin(String userPin, String userCard) throws IOException {
        checkPin = message.substring(12, 16);
        checkUserCard = message.substring(19, 35);
        if ((checkPin + checkUserCard).hashCode() == (userPin + userCard).hashCode()) {
            logger.info("correct PIN entered");
            return false;
        } else {
            System.out.println(Keywords.WRONG_PIN);
            logger.warn("WRONG PIN entered");
            OutputStream outputS = socket.getOutputStream();
            DataOutputStream outputData = new DataOutputStream(outputS);
            outputData.writeUTF(Keywords.WRONG_PIN);
            closeSocket();
            return true;
        }
    }
}